package top.zlcode.common.httpclient.service;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Component;
import top.zlcode.common.core.enums.ResultCode;
import top.zlcode.common.httpclient.enums.MediaTypeEnums;
import top.zlcode.common.security.exception.ServiceException;

import java.io.IOException;
import java.util.Map;

@Component
@Slf4j
public class HttpClientService {

    private final OkHttpClient okHttpClient;

    public HttpClientService(OkHttpClient okHttpClient) {
        this.okHttpClient = okHttpClient;
    }

    /**
     * 简单的 get 请求
     * @param url 请求地址
     */
    public String get(String url) {
        Request request = new Request.Builder().url(url).build();
        return getResponseBody(request);
    }

    /**
     * 简单的 get 请求携带请求头
     * @param url 请求地址
     */
    public String get(String url, Map<String, String> headers) {
        Request request = buildGetRequest(url, headers);
        return getResponseBody(request);
    }

    /**
     * 简单的 get 请求携带请求头
     * @param url 请求地址
     */
    public <T> T get(String url, Map<String, String> headers, Class<T> clazz) {
        Request request = buildGetRequest(url, headers);
        String respBody = getResponseBody(request);
        return  JSON.parseObject(respBody, clazz);
    }

    /**
     * 简单的 post 请求, 发送 json 数据
     * @param url 请求地址
     */
    public String postJson(String url, Object body) {
        Request request = new Request.Builder().url(url).post(RequestBody.create(JSON.toJSONString(body), MediaTypeEnums.JSON_UTF8.getParse())).build();
        return getResponseBody(request);
    }

    /**
     * 简单的 post 请求, 发送 json 数据
     * @param url 请求地址
     */
    public <T> T postJson(String url, Object body, Class<T> clazz) {
        Request request = new Request.Builder().url(url).post(RequestBody.create(JSON.toJSONString(body), MediaTypeEnums.JSON_UTF8.getParse())).build();
        String respBody = getResponseBody(request);
        return JSON.parseObject(respBody, clazz);
    }

    /**
     * 简单的 post 请求, 发送 json 数据, 携带请求头
     * @param url 请求地址
     */
    public String postJson(String url, Object body,  Map<String, String> headers) {
        Request request = buildPostRequest(url, body, headers);
        return getResponseBody(request);
    }

    /**
     * 简单的 post 请求, 发送 json 数据, 携带请求头
     * @param url 请求地址
     */
    public <T> T postJson(String url, Object body,  Map<String, String> headers, Class<T> clazz) {
        Request request = buildPostRequest(url, body, headers);
        String respBody = getResponseBody(request);
        return JSON.parseObject(respBody, clazz);
    }

    /**
     * 通过 request 对象执行请求
     * @param request 请求实体
     */
    public String execute(Request request)  {
        return getResponseBody(request);
    }

    /**
     * 通过 request 对象执行请求
     * @param request 请求实体
     */
    public <T> T execute(Request request, Class<T> clazz) {
        String respBody = getResponseBody(request);
        return JSON.parseObject(respBody, clazz);
    }

    /**
     * 构造请求对象
     */
    private static Request buildPostRequest(String url, Object body, Map<String, String> headers) {
        // 创建请求构建器
        Request.Builder requestBuilder = new Request.Builder().url(url);

        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                requestBuilder.addHeader(entry.getKey(), entry.getValue());
            }
        }

        // 创建请求体
        RequestBody requestBody = RequestBody.create(
                JSON.toJSONString(body),
                MediaTypeEnums.JSON_UTF8.getParse()
        );

        // 构建请求并发送
        return requestBuilder.post(requestBody).build();
    }

    private static Request buildGetRequest(String url, Map<String, String> headers) {
        // 1. 创建请求构建器
        Request.Builder requestBuilder = new Request.Builder().url(url);

        // 2. 遍历并添加请求头（处理null情况，避免空指针）
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> header : headers.entrySet()) {
                // 跳过键或值为null的情况，避免异常
                if (header.getKey() != null && header.getValue() != null) {
                    requestBuilder.addHeader(header.getKey(), header.getValue());
                }
            }
        }

        // 3. 构建请求并获取响应
        return requestBuilder.build();
    }

    /**
     * 请求获取响应
     * @param request 请求实体
     */
    private String getResponseBody(Request request)  {
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful()) {
                return response.body() != null ? response.body().string() : null;
            } else {
                log.error("接口: {}, 调用失败! 状态码: {}, 响应 body: {}", request.url(), response.code(), response.body());
                throw new ServiceException(ResultCode.ERROR);
            }
        } catch (IOException e) {
            log.error("请求失败: 异常信息: ", e);
            throw new ServiceException(ResultCode.FAILED);
        }
    }
}
